/**
********************************************************************************
* @file     lv_port_indev_mouse.c
* @brief    对文件的简要说明
* @details  对文件的详细说明
* @author   jcai
* @date     2024-07-11 23:10:19
* @copyright Copyright &copy; 2024 wy1107412334@163.com All rights reserved
* @version  v0.0.1
*
* \n Email:  wy1107412334@163.com
* \n Blog:   None
* \n Github: https://github.com/wy1107412334
* \n Gitee:  https://gitee.com/git.git1107412334.com
*
********************************************************************************
* @note
* None.
********************************************************************************
* @attention
* None.
********************************************************************************
@verbatim
@endverbatim
********************************************************************************
* @par 历史记录
* jcai, 2024-07-11 23:10:19
* - 首次编写
*
*<center>Copyright &copy; 2024 wy1107412334@163.com All rights reserved</center>
********************************************************************************
*/

/* 头文件导入区 ------------------------------------------------------------- */
#ifdef EN_MOUSE

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#include "lv_port_indev_mouse.h"
#include "sdl_render.h"


/** @defgroup LV_PORT_INDEV_MOUSE LV_PORT_INDEV_MOUSE
* @brief lv_port_indev_mouse modules
* @{
*/



/* 私有宏定义区 ------------------------------------------------------------- */






/* 私有数据类型声明区 ------------------------------------------------------- */

struct mouse_data
{
    sdl_event_handle_arr_t  eventsInfo;
    SDL_Event               cur;
    SDL_Point               prvePos;
};


static void mouse_event(const SDL_Event *, void *, void *);




/* 私有变量定义区 ----------------------------------------------------------- */


static sdl_event_handle_t events[] = {
    { .type = SDL_MOUSEMOTION, .fn = mouse_event, .arg = NULL },
    { .type = SDL_MOUSEBUTTONDOWN, .fn = mouse_event, .arg = NULL },
    { .type = SDL_MOUSEBUTTONUP, .fn = mouse_event, .arg = NULL },
};



/** @defgroup LV_PORT_INDEV_MOUSE_Exported_Variables lv_port_indev_mouse exported variables
* @brief 全局变量定义
* @{
*/



/** defgroup LV_PORT_INDEV_MOUSE_Exported_Variables
* @}
*/





/* 私有函数定义区 ----------------------------------------------------------- */


static void mouse_event(const SDL_Event * e, void * lvglDrv, void * arg)
{
    (void) arg;

    struct mouse_data * p = lv_indev_get_driver_data(lvglDrv);
    int saveDataFlg = 0;

    if ((e->type == SDL_MOUSEBUTTONUP) || (e->type == SDL_MOUSEBUTTONDOWN))
    {
        saveDataFlg = 1;
    }
    else if (e->type == SDL_MOUSEMOTION)
    {
        saveDataFlg = 1;
    }

    if (saveDataFlg)
    {
        p->cur = *e;
        p->prvePos.x = e->button.x;
        p->prvePos.y = e->button.y;
    }
}


/*Get the x and y coordinates if the mouse is pressed*/
static void mouse_get_xy(struct mouse_data * p, int32_t * x, int32_t * y)
{
    /*Your code comes here*/
    *x = p->prvePos.x;
    *y = p->prvePos.y;
}

/*Return true is the mouse button is pressed*/
static bool mouse_is_pressed(struct mouse_data * p)
{
    /*Your code comes here*/

    if ((p->cur.button.state == SDL_PRESSED) && (p->cur.button.button == 1))
    {
        return true;
    }

    return false;
}


static void mouse_read(lv_indev_t * indev_drv, lv_indev_data_t * data)
{
    struct mouse_data * p = lv_indev_get_driver_data(indev_drv);

    /*Get the current x and y coordinates*/
    mouse_get_xy(p, &data->point.x, &data->point.y);

    /*Get whether the mouse button is pressed or released*/
    if(mouse_is_pressed(p)) {
        data->state = LV_INDEV_STATE_PRESSED;
    }
    else {
        data->state = LV_INDEV_STATE_RELEASED;
    }
}





/** @defgroup LV_PORT_INDEV_MOUSE_Exported_Functions lv_port_indev_mouse exported functions
* @brief 全局函数定义
* @{
*/



/**
********************************************************************************
* @brief    简要说明
* @details  详细说明
* @param    none
* @param[in]     a: 该参数用于输入
* @param[in,out] b: 该参数用于输入和输出
* @param[out]    c: 该参数用于输出
* @retval  none
* @retval  0 函数成功
* @retval  1 函数失败
* @return  返回0成功；否则失败
* @note    none
*/
void lv_port_indev_mouse_init(void)
{
    struct mouse_data * p = malloc(sizeof(*p));
    if (p == NULL)  return;
    bzero(p, sizeof(*p));

    lv_indev_t * indev_mouse = lv_indev_create();
    lv_indev_set_type(indev_mouse, LV_INDEV_TYPE_POINTER);
    lv_indev_set_read_cb(indev_mouse, mouse_read);
    lv_indev_set_driver_data(indev_mouse, p);

    lv_obj_t * label = lv_label_create(lv_screen_active());
    lv_label_set_text_static(label, LV_SYMBOL_TINT);
    lv_indev_set_cursor(indev_mouse, label);

    p->eventsInfo.lvglDrv = indev_mouse;
    p->eventsInfo.arr = events;
    p->eventsInfo.arrlen = sizeof(events) / sizeof(events[0]);

    void * handle = lv_display_get_driver_data(lv_indev_get_display(indev_mouse));
    sdl_event_listen(handle, &p->eventsInfo);
}


/** defgroup LV_PORT_INDEV_MOUSE_Exported_Functions
* @}
*/

/** defgroup LV_PORT_INDEV_MOUSE
* @}
*/


#endif
/*********************************** END OF FILE ******************************/
